package com.kt.common.collections

import com.kt.common.func.println
import com.kt.common.func.sum
import com.kt.common.swap
import java.util.*

fun main() {
    //forEach 循环 - 不改变原有函数结构 forEach
    val list = mutableListOf<Int>(1, 3, 5, 7, 9)
    val list1 = mutableListOf(1, null, 5, 7, 9)
    /*list.forEach {
        print("$it \n")
    }*/

    // filter 过滤 -- 返回一个新的函数
    /*val filterList = list.filter {
        it > 3
    }
    filterList.println()*/

    // map 映射-从一个集合转换到另一个集合
    /*val maps = list.map {
        it + 3
    }
    maps.println()*/

    //mapIndexed 映射-从一个集合转换到另一个集合(会存在index与item)
    /*val mapIndexed = list.mapIndexed { index, i ->
        index + i
    }
    mapIndexed.println()*/

    //mapNotNull 映射-从一个集合转换到另一个集合可以剔除返回空的元素
    /*val mapNotNull = list.mapNotNull {
        if (it < 5) null
        else it * 2
    }
    mapNotNull.println()*/

    //mapNotNull 映射-从一个集合转换到另一个集合可以剔除返回空的元素
    /* val mapIndexedNotNull = list.mapIndexedNotNull { index, v ->
         if (index < 3) null
         else index * v
     }
     mapIndexedNotNull.println()*/

    /**合拢*/
    //zip - 合拢 -返回list<Pair>  可通过toMap转换成map来使用
    /*val colors = listOf("red", "brown", "grey")
    val animals = listOf("fox", "bear", "wolf")
    val zips = colors.zip(animals)
    zips.toMap().println()
    println((zips[0] as Pair<String,String>).toList())*/

    //反向转换 - 将list中pair分割成两个list
    /*val listOf = listOf("one" to 1, "two" to 2, "three" to 3, "four" to 4)
    val toMap = listOf.toMap()
    println(toMap["one"])
    println(listOf.unzip())*/

    /**关联*/
    /*val numbers = listOf("one", "two", "three", "four")
    println(numbers.associateWith { it.length })*/

    /*val numbers = listOf("one", "two", "three", "four")

    println(numbers.associateBy { it.first().uppercase() })
    println(numbers.associateBy(keySelector = { it.last().uppercase() }, valueTransform = { it.length }))*/

    /*val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5, 6), setOf(1, 2))
    println(numberSets.flatten())*/
    /*data class StringContainer(val values: List<String>)
    val containers = listOf(
        StringContainer(listOf("one", "two", "three")),
        StringContainer(listOf("four", "five", "six")),
        StringContainer(listOf("seven", "eight"))
    )
    println(containers.flatMap { it.values })*/

    /*val numbers = listOf("one", "two", "three", "four")
    println(numbers)
    println(numbers.joinToString(separator = "->",prefix = "[",postfix = "]"))*/
    /*val numbers1 = (1..100).toList()
    println(numbers1.joinToString(separator = "|",prefix = "[",postfix = "]",limit = 20,truncated = "...***"))*/

    /*val numbers = listOf("one", "two", "three", "four")
    println(numbers.joinToString { "Element: ${it.uppercase()}"})*/
    /*val numbers = listOf("one", "two", "three", "four")
    val (match, rest) = numbers.partition { it.length > 3 }

    println(match)
    println(rest)*/

    /*val numbers = listOf("one", "two", "three", "four")
    println(numbers.any { it.startsWith("f") })//true
    println(numbers.none { it.startsWith("f") })//false
    println(numbers.all { it.startsWith("f") })//false*/

    /* val numbers = listOf("one", "two", "three", "four")
     val list2 = numbers + "five"
     val list3 = numbers.plus("six")
     println(list2)
     println(list3)
     println(list3.minus("four"))
     println(list3 - "four")*/

    val numbers = listOf("one", "two", "three", "four", "five")

    /*println(numbers.groupBy { it.first().uppercase() })
    println(numbers.groupBy(keySelector = { it.first() }, valueTransform = { it.uppercase() }))*/
    //println(numbers.groupingBy { it.first() }.eachCount())
    val nums = listOf(1, 3, 4, 5, 6, 7, 8, 9)
    /* println(nums.groupingBy { it % 2 == 0 }.fold(0) { sum, e ->
         println("sum=$sum,e=$e")
         sum + e
     })*/

    /*println(nums.groupingBy { it % 2 == 0 }.reduce { key, sum, element -> println("sum=$sum,e=$element,key=$key")
        sum + element } )*/

//    val numbers1 = listOf("one", "two", "three", "four", "five", "six")
//    println(numbers1.slice(0..3))//[one, two, three, four]
//    println(numbers1.slice(5 downTo 1 step 2))//[six, four, two]
//    println(numbers1.slice(setOf(5,3,0)))//[six, four, one]

    /*println(numbers.take(8))
    println(numbers.takeLast(3))
    println(numbers.drop(3))
    println(numbers.dropLast(4))*/

    /* val numbers11 = (0..13).toList()
     println(numbers11.chunked(3))
     println(numbers.windowed(4))*/

    /* val numbers1 = linkedSetOf("one", "two", "three", "four", "five")
     println(numbers1.elementAt(3))

     val numbersSortedSet = sortedSetOf("one", "two", "three", "four")
     println(numbersSortedSet.elementAt(1)) // 元素以升序存储*/

    val numbers1 = listOf("one", "two", "three", "four", "five")
    /*println(numbers1.first())
    println(numbers1.last())*/
    /* println(numbers1.first {
         it.length>3
     })
     println(numbers1.last {
         it.startsWith("t")
     })*/

    /*println(numbers1.firstOrNull())
    println(numbers1.lastOrNull(){
        it.length>6
    })*/
    /*println(numbers1.find { it.length>6 })
    println(numbers1.findLast { it.length>3 })*/
    /*println(numbers1.random())
    println(numbers1.randomOrNull())
    println(numbers1.randomOrNull())*/

    /*println(numbers1.contains("one"))
    println(numbers1.contains("one1"))
    println("two" in  numbers1)*/
    /*val numbers2 = listOf("one", "two", "three", "four", "five", "six")
    println(numbers2.isEmpty())
    println(numbers2.isNotEmpty())

    val empty = emptyList<String>()
    println(empty.isEmpty())
    println(empty.isNotEmpty())*/


    //Map  的映射操作 mapKeys & mapValues
    val maps = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
    /*val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
    val filteredMap = numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10}
    println(filteredMap)*/
    /*val filterKeys = maps.filterKeys { it.endsWith("1")  }
    println(filterKeys)
    val filterValues = maps.filterValues { it > 2 }
    println(filterValues)*/
    //改变key，而val不需要变
    /* val mapKeys = maps.mapKeys {
         it.key.uppercase()
     }
     mapKeys.println()*/

    //改变val，而key不需要变
    /*val mapValues = maps.mapValues {
        it.value * 2
    }
    mapValues.println()*/


    val lengthComparator = Comparator { o1: String, o2: String ->
          o2.length - o1.length
    }

    //println(listOf("c","bbddd","ddd","eeeeee").sortedWith(lengthComparator))
    /*println(listOf("c","bbddd","ddd","eeeeee").sortedWith(compareBy{
        it.length
    }))*/

    /*println(listOf("c","bbddd","ddd","eeeeee").sorted())
    println(listOf("c","bbddd","ddd","eeeeee").sortedDescending())*/

    /*println(numbers.sortedBy { it.length })
    println(numbers.sortedByDescending { it.last() })*/
    /*println(numbers.reversed())
    val message = numbers.asReversed()
    println(message)*/

//    println(numbers.shuffled())

    //聚合操作
    val nums1 = listOf(6, 44, 10, 4)
    /*println(nums1.maxOrNull())//返回最大的
    println(nums1.minOrNull())//返回最小的
    println(nums1.average())//返回平均数
    println(nums1.sum())//返回合*/

    /*println(nums1.maxByOrNull { it%3 })
    println(nums1.minByOrNull { it/2 })
    println(nums1.sumOf {  it * 2.0})*/
   /* println(nums1.reduce { sum, e ->  sum +e })
    println(nums1.fold(2) { sum, e ->  sum +e })*/

    /*集合添加操作*/
    /*val n1 = mutableListOf(1, 2, 3, 4)
    n1.add(5)
    println(n1)
    n1.plus(6).println()*/
    /**list相关操作补充*/
    /*val nu2 = listOf(1, 2, 3, 4)
    println(nu2.get(2))
    println(nu2[2])
    println(nu2.getOrNull(5))
    println(nu2.getOrElse(6){
        it/2
    })*/

    val nu3 = (0..13).toList()
//    println(nu3.subList(3,6))
    val nu4 = mutableListOf(1, 2, 3, 4, 2, 5)
    /*println(nu4.indexOf(2))
    println(nu4.lastIndexOf(2))*/
    /*println(nu4.indexOfFirst { it>2 })
    println(nu4.indexOfLast { it%2 ==0 })*/
    /*二分查找*/
    /*val nu4Sort = nu4.sortedWith(compareBy { it })
    println(nu4Sort)
    println(nu4Sort.binarySearch(5))
    println(nu4Sort.binarySearch(6))
    println(nu4Sort.binarySearch(2,2,5))
    println(nu4Sort.binarySearch(2,3,5))*/
    /*集合写操作*/
//    nu4.fill(10)
  /*  nu4.sortBy { it  }
    println(nu4)
    *//*删除*//*
    nu4.removeAt(5)
    nu4.remove(2)
    nu4.removeLast()
    nu4.removeFirst()
    println(nu4)*/


    /*val listOf11 = listOf(Version(1, 2), Version(1, 3), Version(2, 0), Version(1, 5))
    listOf11.sortedBy {
        it
    }
    listOf11.forEach {
        println("ma= ${it.major} , min=${it.minor}")
    }
    class Version(val major: Int, val minor: Int) : Comparable<Version> {
        override fun compareTo(other: Version): Int {
            if (this.major != other.major) {
                return this.major - other.major
            } else if (this.minor != other.minor) {
                return this.minor - other.minor
            } else return 0
        }
    }

    println(Version(1, 2) > Version(1, 3))
    println(Version(2, 0) > Version(1, 5))*/
}


fun <K, V> Map<K, V>.println() {
    println("size=" + this.size)
    this.forEach {
        println("<${it.key},${it.value}>")
    }
}




